tree grammar VhdlTreeGrammar;

options {
  ASTLabelType = CommonTree; 
  output       = template;
}

// Tokens used internally by Moca
// ID: ('a'..'z' | 'A'..'Z')+;
// STRING: ( ID | ('0'..'9') )+; 
// ATRIBUTE: Used as an imaginary token for coding attributes in XML files (ATTRIBUTE name=ID value=STRING)
tokens {
  ID;
  STRING;
  ATTRIBUTE; 
} 
  
@header {
package org.moflon.moca.vhdl.unparser;
}
// tree grammar rules:
main: ^('VHDL' (entities+=entity beh+=behaviour)*)
    -> vhdl(entities={$entities}, beh={$beh});

entity: ^('entity' name=STRING ports+=port*)
    -> entity(name={$name}, ports={$ports});

port: ^('PORT' name=STRING dir=STRING logic=STRING)
    -> port(name={$name}, dir={$dir}, logic={$logic});

behaviour: ^('GATE' block=STRING exp+=logicExp*) 
    -> gate(block={$block}, exp={$exp})
    | ^('BLOCK' block=STRING signals+=signal* mappings+=map*)
    -> struct(block={$block}, signals={$signals}, mappings={$mappings})
    ;
    
logicExp: ^(portName=STRING op)
    -> expression(portName={$portName}, exp={$op.st});
    
op: ^('not' in=STRING)
  -> not(in={$in})
  | ^('and' in1=STRING in2=STRING)
  -> and(in1={$in1}, in2={$in2})
  | ^('or' in1=STRING in2=STRING)  
  -> or(in1={$in1}, in2={$in2})
  ;
  
signal: ^('signal' name=STRING type=STRING)  
  -> signal(name={$name}, type={$type});
  
map: ^(name=STRING forwardings+=forwarding*)
  -> map(name={$name}, forwardings={$forwardings});
  
forwarding: ^('=' internal=STRING external=STRING)
  -> forwarding(internal={$internal}, external={$external});